package com.se.dao.mysql;

import com.se.domain.mysql.ActivityDO;
import com.se.domain.request.param.CreateActParam;
import com.se.enums.ResultCode;
import com.se.exception.ResultException;
import com.se.mapper.ActMapper;
import org.apache.ibatis.session.SqlSession;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;

import java.sql.SQLException;
import java.util.*;

@Repository
public class ActDao {
    @Autowired
    ActMapper actMapper;
    @Autowired
    SqlSession sqlSession;

    public Map<Long, ActivityDO> mapByActIdList(List<Long> actIds) {
        if(actIds.isEmpty()){
            return new TreeMap<>();
        }
        List<ActivityDO> doList = actMapper.listByActIdList(actIds);

        Map<Long, ActivityDO> map = new HashMap<>();
        for (ActivityDO activityDO : doList) {
            map.put(activityDO.getActId(), activityDO);
        }

        return map;
    }

    public ActivityDO createAct(CreateActParam param, Long userId) {
        ActivityDO activityDO = new ActivityDO(param, userId);
        actMapper.insertActivity(activityDO);

        return activityDO;
    }

    public ActivityDO getByActId(Long actId) {
        return actMapper.getByActId(actId);
    }


    public void updateAct(ActivityDO activityDO) {
        actMapper.updateAct(activityDO);
    }

    public void publishByActId(Long actId) {
        actMapper.updatePublishByActId(actId, true);
    }

    public void cancelPublishByActId(Long actId) {
        actMapper.cancelPublishByActId(actId);
//        actMapper.updatePublishByActId(actId, false);
    }

    public void deleteByCatId(Long actId) {
        actMapper.logicDeleteByActId(actId);
    }

    public void updateQnIdByActId(Long qnId, Long actId) {
        actMapper.updateQnIdByActId(qnId, actId);
    }

    @Transactional
    public void incrementApplyNum(Long actId) throws ResultException {
//        try {
//            sqlSession.getConnection().setAutoCommit(false);
//            try {
//                ActivityDO activityDO = sqlSession.getMapper(ActMapper.class).selectForUpdate(actId);
////                if(activityDO.getSize() > 0 && activityDO.getApplyNum() < activityDO.getSize()){
////                    sqlSession.getMapper(ActMapper.class).incrementApplyNum(actId);
////                }
//                if(activityDO.getSize() != -1 && activityDO.getSize() <= activityDO.getApplyNum()){
//                    throw new ResultException(ResultCode.SIZE_FULL);
//                }
//                sqlSession.getMapper(ActMapper.class).incrementApplyNum(actId);
//                sqlSession.commit();
//            }catch (Exception e){
//                // 发生异常时回滚事务
//                sqlSession.rollback();
//                throw e;
//            }finally {
//                sqlSession.getConnection().setAutoCommit(true);
//            }
//
//
//        } catch (SQLException e) {
//            throw new RuntimeException(e);
//        }


        ActivityDO activityDO = actMapper.selectForUpdate(actId);
        if(activityDO.getSize() != -1 && activityDO.getSize() <= activityDO.getApplyNum()){
            throw new ResultException(ResultCode.SIZE_FULL);
        }
        actMapper.incrementApplyNum(actId);

    }

    @Transactional
    public void decrementApplyNum(Long actId) {
//        try {
//            sqlSession.getConnection().setAutoCommit(false);
//            try {
//                ActivityDO activityDO = sqlSession.getMapper(ActMapper.class).selectForUpdate(actId);
//                sqlSession.getMapper(ActMapper.class).decrementApplyNum(actId);
//                sqlSession.commit();
//            }catch (Exception e){
//                // 发生异常时回滚事务
//                sqlSession.rollback();
//                throw e;
//            }finally {
//                sqlSession.getConnection().setAutoCommit(true);
//            }
//
//        } catch (SQLException e) {
//            throw new RuntimeException(e);
//        }
        actMapper.selectForUpdate(actId);
        actMapper.decrementApplyNum(actId);
    }

    public List<ActivityDO> listByUserId(Long userId, String order, Boolean desc, Integer page, Integer size) {

        return actMapper.listByUserId(userId, order, desc, page*size, size);
    }

    public List<ActivityDO> listByQnIds(List<Long> qnIdList) {
        return null;
    }

    public Map<Long, ActivityDO> mapByQnIds(List<Long> qnIdList) {
        if(qnIdList.isEmpty()){
            return Collections.emptyMap();
        }
        List<ActivityDO> activityDOList = actMapper.listByQnIds(qnIdList, null, true, 0, Integer.MAX_VALUE);
        if(activityDOList.isEmpty()){
            return Collections.emptyMap();
        }

        Map<Long, ActivityDO> map = new HashMap<>();
        for (ActivityDO activityDO : activityDOList) {
            map.put(activityDO.getQnId(), activityDO);
        }

        return map;
    }

    public ActivityDO getByQnId(Long qnId) {
        if(qnId == null){
            return null;
        }
        return actMapper.getByQnId(qnId);
    }
}
